package com.atguigu.gmall.config;


import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.constant.RedisConst;
import com.atguigu.gmall.entity.GmallCorrelationData;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Map;

@Component
public class MQProducerAckConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);            //指定 ConfirmCallback
        rabbitTemplate.setReturnCallback(this);             //指定 ReturnCallback
    }
    //交换机应答    发消息成功或失败都是应答
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        //boolean ack : 应答状态   true 表示接收到了 false:表示未接收到
        if(ack){
            System.out.println("收到");
        }else{
            System.out.println("未收到的原因是：" + cause);
            //未收到的处理方案：重新发送  3次机会  打日志
            reSendMessage(correlationData);
        }

    }
    //重新发送
    public void reSendMessage(CorrelationData correlationData){
        GmallCorrelationData correlationData1 = (GmallCorrelationData) correlationData;
        //判断发送的次数
        int retryCount = correlationData1.getRetryCount();
        if(retryCount <= 2){
            retryCount++;
            System.out.println("第" + retryCount + "次");
            correlationData1.setRetryCount(retryCount);
            //更新Redis中correlationData1
            redisTemplate.opsForHash().put(RedisConst.REPLY_MESSAGE,
                    correlationData1.getId(),JSONObject.toJSONString(correlationData1));
            //发消息
            rabbitTemplate.convertAndSend(correlationData1.getExchange(),
                    correlationData1.getRoutingKey(),correlationData1.getMessage(),
                    correlationData1);
        }


    }


    @Autowired
    private RedisTemplate redisTemplate;

    //队列应答  只能失败了才应答  成功是不应答
    //Message : 消息体
    //replyCode : 失败的状态码 404
    //replyText : NOT FOUND
    //exchange : 交换机
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        //执行  肯定是失败了
        System.out.println(message.getBody());
        System.out.println(replyCode);
        System.out.println(replyText);
        System.out.println(exchange);
        System.out.println(routingKey);
        //spring_returned_message_correlation -> 64d1a7d6-2d23-4391-b57f-70d74c32a0d8
        String id = message.getMessageProperties()
                .getHeader("spring_returned_message_correlation");
        String json = (String) redisTemplate.opsForHash()
                .get(RedisConst.REPLY_MESSAGE, id);

        GmallCorrelationData gmallCorrelationData = JSONObject.parseObject(json, GmallCorrelationData.class);
        //判断
        if(gmallCorrelationData.isDelay()){
            return;
        }
        //队列失败应答：处理结果重新发送
        reSendMessage(gmallCorrelationData);
    }






}
